package ru.ntcreb.csir.gui;

import java.util.Iterator;
import java.util.List;

import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import ru.ntcreb.csir.libs.methods.SVCH.SVCHService;
import ru.ntcreb.csir.libs.methods.SVCH.TractService;
import ru.ntcreb.csir.libs.methods.SVCH.dto.SVCHImpulseDTO;
import ru.ntcreb.csir.libs.methods.SVCH.dto.TractDTO;

public class FXMLController extends Application {
	final private int MAX_PARALLEL_ITERATIONS = 90;
	final private String TRACT1_CHART_NAME = "tract1_chart";
	final private String TRACT2_CHART_NAME = "tract2_chart";
	final private String MICROWAVE_REACTION_CHART_NAME = "microwave_reaction_chart";
	final private String MICROWAVE_CHART_NAME = "microwave_chart";
	final private String CONNECTION_TRACT_CHART_NAME = "connection_tract_chart";

	final TractService tractService = new TractService();
	final SVCHService svchService = new SVCHService();

	public static void main(String[] args) {
		launch(args);
	}

	@Override
	public void start(Stage stage) throws Exception {

		ScrollPane root = FXMLLoader.load(getClass().getResource("/111.fxml"));

		Scene scene = new Scene(root, 944, 602);

		final ScrollPane scrollPane = (ScrollPane) scene.lookup("#scrollPane");
		final AnchorPane anchor = (AnchorPane) scrollPane.getContent();
		final SplitPane splitPaneGrid = (SplitPane) anchor
				.lookup("#split_pane_grid");
		final GridPane gridPane = (GridPane) splitPaneGrid.getItems().get(1);
		final List<Node> gridChildren = gridPane.getChildren();
		final LineChart<Number, Number> tractChart = (LineChart<Number, Number>) gridChildren
				.get(0);

		// TODO: must be false, improve performance significally
		tractChart.setCreateSymbols(false);

		final LineChart<Number, Number> microwaveChart = (LineChart<Number, Number>) gridChildren
				.get(1);
		// TODO: must be false, improve performance significally
		microwaveChart.setCreateSymbols(false);

		final LineChart<Number, Number> microwaveReactionChart = (LineChart<Number, Number>) gridChildren
				.get(2);
		// TODO: must be false, improve performance significally
		microwaveReactionChart.setCreateSymbols(false);

		final ProgressIndicator progressTractIndicator = (ProgressIndicator) gridChildren
				.get(4);
		final SplitPane splitPane1 = (SplitPane) anchor.lookup("#splitPane1");
		final AnchorPane anchor2 = (AnchorPane) splitPane1.getItems().get(0);
		final AnchorPane anchor3 = (AnchorPane) anchor2.lookup("#anchor3");
		final Pane pane3 = (Pane) anchor3.lookup("#pane3");
		final Pane pane2 = (Pane) anchor2.lookup("#pane2");

		final RadioButton comprehensive_conn_radio = (RadioButton) pane3
				.getChildren().get(8);
		final RadioButton parallel_conn_radio = (RadioButton) pane3
				.getChildren().get(9);
		Button tract1_button = (Button) anchor2.getChildren().get(2);

		tract1_button.setOnAction(event -> {
			// setProgressIndicatorVisibility(progressTractIndicator, true);
				TractDTO tractDTO = getTractParameters(pane3, true);
				double[] tractArr = tractService.createTractArray(tractDTO);
				setConsistentChartTractValues(tractChart, tractArr,
						TRACT1_CHART_NAME);
				// setProgressIndicatorVisibility(progressTractIndicator,
				// false);
			});

		Button tract2_button = (Button) anchor2.getChildren().get(3);

		tract2_button.setOnAction(event -> {
			// setProgressIndicatorVisibility(progressTractIndicator, true);
				TractDTO tractDTO = getTractParameters(pane3, false);
				double[] tractArr = tractService.createTractArray(tractDTO);
				setConsistentChartTractValues(tractChart, tractArr,
						TRACT2_CHART_NAME);
				// setProgressIndicatorVisibility(progressTractIndicator,
				// false);
			});

		Button connection_button = (Button) anchor2.getChildren().get(4);

		connection_button.setOnAction(event -> {

			TractDTO tract1DTO = getTractParameters(pane3, true);
			TractDTO tract2DTO = getTractParameters(pane3, false);

			if (comprehensive_conn_radio.isSelected()) {
				double[] tractArr = tractService
						.createConsistentTwoTractsArray(tract1DTO, tract2DTO);
				setConsistentChartTractValues(tractChart, tractArr,
						CONNECTION_TRACT_CHART_NAME);
			}

			else if (parallel_conn_radio.isSelected()) {
				double[] tractArr = tractService.createParallelTwoTractsArray(
						tract1DTO, tract2DTO);

				setParallelChartTractValues(tractChart, tractArr,
						CONNECTION_TRACT_CHART_NAME);
			}

		});

		Button microwave_impulse_button = (Button) pane2.getChildren().get(0);

		microwave_impulse_button.setOnAction(event -> {

			SVCHImpulseDTO dto = getMicrowaveParameters(pane2);

			setChartMicrowaveValues(microwaveChart, dto, MICROWAVE_CHART_NAME);
		}

		);

		Button microwave_reaction_impulse_button = (Button) pane2.getChildren()
				.get(9);

		microwave_reaction_impulse_button.setOnAction(event -> {

			// TODO
				/*
				 * SVCHImpulseDTO dto = getMicrowaveParameters(pane2); double[]
				 * microwaveArr = svchService.createSVCHImpulse(dto);
				 * 
				 * //TODO we have XYData from Chart1 //and we must use it in our
				 * formula instead of tract parameters double[] tractArr =
				 * svchService.createTractSVCHReaction(microwaveArr, tract1)
				 * setConsistentChartTractValues(microwaveReactionChart,
				 * tractArr, MICROWAVE_REACTION_CHART_NAME);
				 */

			});

		stage.setTitle("FXML Welcome");
		stage.setScene(scene);
		stage.show();
	}

	private void setProgressIndicatorVisibility(
			ProgressIndicator progressIndicator, boolean visible) {
		progressIndicator.setVisible(visible);
	}

	private void setParallelChartTractValues(
			LineChart<Number, Number> lineChart, double[] tractArr,
			String seriesName) {

		XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
		series.setName(seriesName);
		double j = 0.01;
		ObservableList<Data<Number, Number>> seriesData = series.getData();
		for (int i = 0; i < MAX_PARALLEL_ITERATIONS; i++) {

			Data<Number, Number> dataUnit = new XYChart.Data<Number, Number>(
					tractArr[i], j);
			seriesData.add(dataUnit);

			j += 0.01;
		}

		setChartSeries(lineChart, series);

	}

	private void setConsistentChartTractValues(
			LineChart<Number, Number> lineChart, double[] tractArr,
			String seriesName) {

		XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
		series.setName(seriesName);
		double j = 0.1;
		ObservableList<Data<Number, Number>> seriesData = series.getData();
		for (int i = 0; i < 10000; i++) {

			Data<Number, Number> dataUnit = new XYChart.Data<Number, Number>(j,
					tractArr[i]);
			seriesData.add(dataUnit);
			j += 0.1;
		}

		setChartSeries(lineChart, series);

	}

	private void setChartSeries(LineChart<Number, Number> lineChart,
			XYChart.Series<Number, Number> series) {

		ObservableList<XYChart.Series<Number, Number>> chartData = lineChart
				.getData();
		Iterator<Series<Number, Number>> iter = chartData.iterator();
		int i = 0;
		boolean isInChart = false;
		while (iter.hasNext()) {
			Series<Number, Number> item = iter.next();
			if (item.getName().equals(series.getName())) {
				chartData.set(i, series);
				isInChart = true;
				break;
			}
			i++;
		}
		if (!isInChart) {
			chartData.add(series);
		}

	}

	private void setChartMicrowaveValues(LineChart<Number, Number> lineChart,
			SVCHImpulseDTO svchImpulseDTO, String seriesName) {

		double[] microwaveArr = svchService.createSVCHImpulse(svchImpulseDTO);

		XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
		series.setName(seriesName);
		double time = 0.00000001;
		ObservableList<Data<Number, Number>> seriesData = series.getData();
		for (int i = 0; i < 10000; i++) {
			Data<Number, Number> dataUnit = new XYChart.Data<Number, Number>(
					time, microwaveArr[i]);
			seriesData.add(dataUnit);
			time += 0.00000001;
		}

		ObservableList<XYChart.Series<Number, Number>> chartData = lineChart
				.getData();
		Iterator<Series<Number, Number>> iter = chartData.iterator();
		int i = 0;
		boolean isInChart = false;
		while (iter.hasNext()) {
			Series<Number, Number> item = iter.next();
			if (item.getName().equals(seriesName)) {
				chartData.set(i, series);
				isInChart = true;
				break;
			}
			i++;
		}
		if (!isInChart) {
			chartData.add(series);
		}

	}

	private TractDTO getTractParameters(Node node, boolean isFirstTract) {

		TextField K, N, U0, S;
		double K_double, N_double, U0_double, S_double;
		if (isFirstTract) {
			K = (TextField) node.lookup("#K1");
			N = (TextField) node.lookup("#N1");
			U0 = (TextField) node.lookup("#U01");
			S = (TextField) node.lookup("#S1");

		} else {
			K = (TextField) node.lookup("#K2");
			N = (TextField) node.lookup("#N2");
			U0 = (TextField) node.lookup("#U02");
			S = (TextField) node.lookup("#S2");
		}

		K_double = new Double(K.getText());
		N_double = new Double(N.getText());
		U0_double = new Double(U0.getText());
		S_double = new Double(S.getText());

		return tractService.createTractDTO(K_double, N_double, U0_double,
				S_double);

	}

	private SVCHImpulseDTO getMicrowaveParameters(Pane node) {

		TextField A, alpha, beta, U0;
		double A_double, alpha_double, beta_double, U0_double;
		ObservableList<Node> paneChildren = node.getChildren();
		A = (TextField) paneChildren.get(1);
		alpha = (TextField) paneChildren.get(2);
		beta = (TextField) paneChildren.get(3);
		U0 = (TextField) paneChildren.get(4);

		A_double = new Double(A.getText());
		alpha_double = new Double(alpha.getText());
		beta_double = new Double(beta.getText());
		U0_double = new Double(U0.getText());

		return svchService.createSVCHImpulseDTO(A_double, alpha_double,
				beta_double, U0_double);

	}

}
